using System;
using System.Collections.Generic;
using System.Text;
using C5;

namespace CoreCalc.SheetDefinedFunctions
{
  public class CellsUsedInFunctions
  {
    private readonly HashDictionary<FullCellAddr, HashSet<string>> addressToFunctionList;
    private readonly HashDictionary<string, List<FullCellAddr>> functionToAdressList;

    public CellsUsedInFunctions()
    {
      addressToFunctionList = new HashDictionary<FullCellAddr, HashSet<string>>();
      functionToAdressList = new HashDictionary<string, List<FullCellAddr>>();
    }

    internal C5.ICollection<string> GetMethodsForAdresses(FullCellAddr[] adresses)
    {
      HashSet<string> list = new HashSet<string>();
      foreach (FullCellAddr addr in adresses)
      {
        HashSet<string> items;
        if (addressToFunctionList.Find(addr, out items))
          list.AddAll(items);
      }
      return list;
    }

    internal void AddFunction(string info, C5.ICollection<FullCellAddr> addrs)
    {
      foreach (FullCellAddr addr in addrs)
        AddCellToFunction(info, addr);
      List<FullCellAddr> addrsList = new List<FullCellAddr>(addrs);
      functionToAdressList.UpdateOrAdd(info, addrsList);
    }

    internal void RemoveFunction(string info)
    {
      List<FullCellAddr> addresses;
      if (!functionToAdressList.Find(info, out addresses))
        return;

      foreach (FullCellAddr addr in addresses)
        addressToFunctionList.Remove(addr);
 
      functionToAdressList.Remove(info);
    }

    private void AddCellToFunction(string info, FullCellAddr addr)
    {
      HashSet<string> infos;
      if (!addressToFunctionList.Find(addr, out infos))
        infos = new HashSet<string>();
      infos.Add(info);
      addressToFunctionList.UpdateOrAdd(addr, infos);
    }
  }
}
